package http

import (
	"bytes"
	"fmt"
	"gitee.com/dongmingchao/decent-ft/src/caretaker"
	"gitee.com/dongmingchao/decent-ft/src/courier"
	"gitee.com/dongmingchao/decent-ft/src/utils"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
)

func hello(w http.ResponseWriter, r *http.Request) {
	name := strings.Replace(r.URL.Path, "/hello/", "", 1)

	w.Header().Set("Content-Type", "text/plain")
	w.WriteHeader(http.StatusOK)

	io.WriteString(w, fmt.Sprintf("Hello %s\n", name))
}

func search(w http.ResponseWriter, r *http.Request) {
	name := strings.Replace(r.URL.Path, "/search/", "", 1)
	if name == "" {
		w.Header().Set("Content-Type", "application/json")
		io.WriteString(w, caretaker.GlobalStash.String())
		return
	}
	resHashes := caretaker.GlobalStash.SearchFileHash(name)
	var content bytes.Buffer
	if len(resHashes) == 0 {
		content = *courier.BridgeSearchFileContent(name, nil, nil)
	} else if len(resHashes) == 1 {
		content = caretaker.ReadStashFileByMark(resHashes[0])
	} else {
		content = *bytes.NewBufferString("Too much results")
		w.WriteHeader(http.StatusNotFound)
	}
	w.Header().Set("Content-Type", GetFileContentType(content))
	io.Copy(w, &content)
}

func headers(w http.ResponseWriter, req *http.Request) {

	for name, headers := range req.Header {
		for _, h := range headers {
			fmt.Fprintf(w, "%v: %v\n", name, h)
		}
	}
}

func index(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	utils.ReadFile("./src/http/index.html", func(file *os.File) {
		io.Copy(w, file)
	})
}

func Main() {
	http.HandleFunc("/search/", search)
	http.HandleFunc("/hello/", hello)
	http.HandleFunc("/headers", headers)
	http.HandleFunc("/", index)

	http.ListenAndServe(":8090", nil)
}

func GetFileContentType(out bytes.Buffer) string {

	// Only the first 512 bytes are used to sniff the content type.
	buffer := make([]byte, 512)

	_, err := out.Read(buffer)
	if err != nil {
		log.Fatalln("web sever read Error", err)
	}

	// Use the net/http package's handy DectectContentType function. Always returns a valid
	// content-type by returning "application/octet-stream" if no others seemed to match.
	contentType := http.DetectContentType(buffer)

	return contentType
}
